package Client.PokerClient.src;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.GridLayout;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 * Klient tworzacy okno do gry.
 * @author Artur Smolibowski
 */
public class GameWindow {
  /**
   * Zmienna przechowujaca okno glowne programu.
   */
  private JFrame window;
  /**
   * Szerokosc okna.
   */
  private int windowWidth;
  /**
   * Dlugosc okna.
   */
  private int windowHeight;
  /**
   * Przycisk rozpoczecia gry.
   */
  private JButton butStartGame;
  /**
   * Przycisk wyjscia z gry.
   */
  private JButton butLeaveGame;
  /**
   * Przycisk wymiany kart.
   */
  private JButton butChangeCards;
  /**
   * Przycisk nastepnej rozkrywki.
   */
  private JButton butNextDeal;
  /**
   * Lable na ktorym wyswietlany jest zwyciesca oraz czas na wymiane kart.
   */
  private JLabel labTimeAndWiner;
  /**
   * Buffor przechowujacy obrazek z kartami.
   */
  private BufferedImage imgCards;
  /**
   * Label z nazwami graczy.
   */
  private JLabel[] labIDPlayers;
  /**
   * Konstruktor klasy.
   * @param window Okno glowne programu.
   * @param windowWidth Szerokosc okna.
   * @param windowHeight Wysokosc okna.
   */
  GameWindow(JFrame window, int windowWidth, int windowHeight) {
    butStartGame = new JButton("Start Game");
    butStartGame.setBounds(650, 520, 150, 40); 

    butLeaveGame = new JButton("Leave Game");
    butLeaveGame.setBounds(650, 560, 150, 40);

    butChangeCards = new JButton("Change cards");
    butChangeCards.setBounds(300, 380, 200, 40);

    butNextDeal = new JButton("Next Deal");
    butNextDeal.setBounds(300, 380, 200, 40);

    labTimeAndWiner = new JLabel("");
    labTimeAndWiner.setBounds(195, 200, 400, 200);
    labTimeAndWiner.setFont(new Font(labTimeAndWiner.getName(), Font.PLAIN, 45));
    labTimeAndWiner.setHorizontalAlignment(JLabel.CENTER);
    labTimeAndWiner.setVerticalAlignment(JLabel.CENTER);

    labIDPlayers = new JLabel[4];
    labIDPlayers[0] = new JLabel("");
    labIDPlayers[0].setBounds(0, 550, 170, 25);
    labIDPlayers[0].setHorizontalAlignment(JLabel.RIGHT);
    labIDPlayers[0].setVerticalAlignment(JLabel.CENTER);

    labIDPlayers[1] = new JLabel("");
    labIDPlayers[1].setBounds(620, 15, 200, 25);
    labIDPlayers[1].setHorizontalAlignment(JLabel.LEFT);
    labIDPlayers[1].setVerticalAlignment(JLabel.CENTER);

    labIDPlayers[2] = new JLabel("");
    labIDPlayers[2].setBounds(0, 50, 165, 25);
    labIDPlayers[2].setHorizontalAlignment(JLabel.CENTER);
    labIDPlayers[2].setVerticalAlignment(JLabel.CENTER);

    labIDPlayers[3] = new JLabel("");
    labIDPlayers[3].setBounds(610, 510, 200, 25);
    labIDPlayers[3].setHorizontalAlignment(JLabel.CENTER);
    labIDPlayers[3].setVerticalAlignment(JLabel.CENTER);

    butChangeCards.setVisible(false);
    butNextDeal.setVisible(false);
    labTimeAndWiner.setVisible(false);

    try { imgCards  = ImageIO.read(new File("./graphic/cards.gif")); }
    catch(IOException e) { e.getMessage(); System.exit(0); }

    this.window=window;
    this.windowWidth=windowWidth;
    this.windowHeight=windowHeight;
  }
  /**
   * Metoda dodajaca ActionLisnera do tej klasy.
   * @param listener Listener GameWindow.
   */
  public void addActionListener(GameListener listener) {
    butStartGame.addActionListener(listener);
    butLeaveGame.addActionListener(listener);
    butChangeCards.addActionListener(listener);
    butNextDeal.addActionListener(listener);
  }
  /**
   * Funkcja odswierzajaca okno gry.
   * @param PlayersDecks Talia graczy.
   * @param maxPlayers Maksymalna liczba graczy.
   * @param ReplaceCards Karty ktore chcemy wymienic.
   */
  public void ChangeWindow(int PlayersDecks[][][], int maxPlayers, int ReplaceCards[]) {
    window.getContentPane().removeAll();

    window.setLayout(new GridLayout());
    window.setSize(windowWidth+5, windowHeight+28);
    window.setLocationRelativeTo(null);

    int x=(int)((windowWidth-5*90)/2);
    int y=windowHeight-150;
    int x2=windowWidth-150;
    int y2=(int)((windowHeight-5*90)/2);

    BufferedImage tmp = new BufferedImage(windowWidth, windowHeight, BufferedImage.TYPE_INT_RGB);
    Graphics2D graph = tmp.createGraphics();
    graph.setPaint(Color.green);
    graph.fillRect(0, 0, tmp.getWidth(), tmp.getHeight());
    for(int i=0;i<5;i++)
      tmp.getGraphics().drawImage(imgCards.getSubimage(PlayersDecks[0][0][i]*125, PlayersDecks[0][1][i]*181, 125, 181), x+i*90, y-ReplaceCards[i], 80, 120, null);

    for(int i=0;i<5 && maxPlayers>1 ;i++) {
      tmp.getGraphics().drawImage(rotate(imgCards.getSubimage(PlayersDecks[1][0][i]*125, PlayersDecks[1][1][i]*181, 125, 181),Math.toRadians(180)), x+i*90, 20, 80, 120, null);
    }

    for(int i=0;i<5 && maxPlayers>2 ;i++) {
        tmp.getGraphics().drawImage(rotate(imgCards.getSubimage(PlayersDecks[2][0][i]*125, PlayersDecks[2][1][i]*181, 125, 181), Math.toRadians(90)), 20, y2+i*90, 120, 80, null);
    }

    for(int i=0;i<5 && maxPlayers>3 ;i++) {
      tmp.getGraphics().drawImage(rotate(imgCards.getSubimage(PlayersDecks[3][0][i]*125, PlayersDecks[3][1][i]*181, 125, 181),Math.toRadians(270)), x2, y2+i*90, 120, 80, null);
    }

    JLabel labtmp = new JLabel(new ImageIcon(tmp));

    labtmp.add(butStartGame);
    labtmp.add(butLeaveGame);
    labtmp.add(butChangeCards);
    labtmp.add(butNextDeal);
    labtmp.add(labTimeAndWiner);
    labtmp.add(labIDPlayers[0]);
    labtmp.add(labIDPlayers[1]);
    labtmp.add(labIDPlayers[2]);
    labtmp.add(labIDPlayers[3]);


    window.add(labtmp);

    window.revalidate();
    window.repaint();
  }
  /**
   * Metoda zluzaca do obrania obrazkow.
   * @param image Obrazek ktory ma zostac obrocony.
   * @param angle Kat o jaki ma zosta obrocony.
   * @return Obrocony obrazek.
   */
  public static BufferedImage rotate(BufferedImage image, double angle) {
    double sin = Math.abs(Math.sin(angle)), cos = Math.abs(Math.cos(angle));
    int w = image.getWidth(), h = image.getHeight();
    int neww = (int)Math.floor(w*cos+h*sin), newh = (int)Math.floor(h*cos+w*sin);
    GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT);
    Graphics2D g = result.createGraphics();
    g.translate((neww-w)/2, (newh-h)/2);
    g.rotate(angle, w/2, h/2); 
    g.drawRenderedImage(image, null);
    g.dispose();
    return result;
  }
  /**
   * Pobranie przycisku rozpoczecia gry.
   * @return Przycisk rozpoczecia gry
   */
  public JButton getStartGame() {
    return butStartGame;
  }
  /**
   * Pobranie przycisku opuszczenia gry.
   * @return Przycisk opuszczenia gry.
   */
  public JButton getLeaveGame() {
    return butLeaveGame;
  }
  /**
   * Pobranie przycisku wymiany kart.
   * @return Przycisk wymiany kart.
   */
  public JButton getChangeCards() {
    return butChangeCards;
  }
  /**
   * Pobranie przycisku nastepnego rozdania.
   * @return Przycisk nastepnego rozdania.
   */
  public JButton getNextDeal() {
    return butNextDeal;
  }
  /**
   * Pobranie labelu z nazwa zwyciescy lub czasu na wymiane kart.
   * @return  Label z nazwa zwyciescy lub czasu na wymiane kart.
   */
  public JLabel getTimeAndWiner() {
    return labTimeAndWiner;
  }
  /**
   * Pobranie labeli z nazwami graczy.
   * @return Labele z nazwami graczy.
   */
  public JLabel[] getIDPlayers() {
    return labIDPlayers;
  }
}
